package props

import (
	"gitee.com/night-tc/gobige/global"
	"gitee.com/night-tc/gobige/msgdef/protomsg"
)

// PropsSyncContainer 需要进行属性同步的部分
type PropsSyncContainer struct {
	*PropDirtyMgr

	//需要同步给其他服务器的数据
	DirtySrvProps map[uint32][]IProp

	DirtyAOIMsg   []*protomsg.SyncProp
	DirtyMRoleMsg []*protomsg.SyncProp
}

func NewPropsSyncContainer() *PropsSyncContainer {
	c := &PropsSyncContainer{}
	c.ProsSyncInit()
	return c
}

// Init 初始化
func (c *PropsSyncContainer) ProsSyncInit() {
	c.PropDirtyMgr = NewPropDirtyMgr()
	c.PropDirtyMgr.AddSorter(EDPSorterTypeSync)
	c.PropDirtyMgr.AddSorter(EDPSorterTypeSave)
	c.DirtySrvProps = make(map[uint32][]IProp)
}

// // ProsSyncInitProp 初始化属性列表
// func (c *PropsSyncContainer) ProsSyncInitProp(def *Def, interestSrvType uint32, subType string) {
// 	if def == nil {
// 		logger.Error("ProsSyncInitProp def is nil")
// 		return
// 	}
// 	c.PropDirtyMgr.InitProp(def)
// }

// // ProsSyncInitProp2 初始化属性列表
// func (c *PropsSyncContainer) ProsSyncInitProp2(def *Def, subType string) {
// 	c.PropDirtyMgr.InitProp(def)
// }

////////////////////////////////////////////////////////////////
//打包

// 获取AOI需要的差量属性更新
func (c *PropsSyncContainer) GetDirtyAOIMsg() []*protomsg.SyncProp {
	return c.DirtyAOIMsg
}

// 获取自身需要的差量属性更新
func (c *PropsSyncContainer) GetDirtyMRoleMsg() []*protomsg.SyncProp {
	return c.DirtyMRoleMsg
}

// 打包同步数据：给自己的，给AOI的，给其他服务器的
func (c *PropsSyncContainer) PackPropsSyncProps() {
	/*
		需要每次都生成数据，这样后面就不用再判空了。
		只需要判断成员数量
	*/
	c.DirtyAOIMsg = make([]*protomsg.SyncProp, 0)
	c.DirtyMRoleMsg = make([]*protomsg.SyncProp, 0)
	var dirtyaoi, dirtyrole []IProp
	if l := c.GetDirtyPropSorter(EDPSorterTypeSync).ListCount(); l == 0 {

		// c.DirtySrvProps = make(map[uint8][]*PropInfo)
		return
	} else {
		dirtyaoi = make([]IProp, 0, l)
		dirtyrole = make([]IProp, 0, l)
	}
	c.HandlerSorterResultForeach(EDPSorterTypeSync, func(p IProp) {
		//如果数据需要同步给别的服务器的话
		for _, s := range p.GetField().WatchSrvs {
			if s != global.GetCfgInst().GetDefType() &&
				s != p.GetField().MainSrv {
				m := c.getDirtyProps(s)
				c.DirtySrvProps[s] = append(m, p)
			}
		}
		if p.GetField().IsClient {
			dirtyaoi = append(dirtyaoi, p)
		}
		if p.GetField().IsMRole {
			dirtyrole = append(dirtyrole, p)
		}
	})

	if len(dirtyaoi) > 0 {
		c.DirtyAOIMsg = PackPropsToProtobuf(dirtyaoi)
	}
	if len(dirtyrole) > 0 {
		c.DirtyMRoleMsg = PackPropsToProtobuf(dirtyrole)
	}
}

// 遍历服务器脏数据，会清空脏数据
func (this *PropsSyncContainer) ForEachSrvDirty(f func(uint32, []IProp)) {
	for s, v := range this.DirtySrvProps {
		this.DirtySrvProps[s] = v[0:0]
		f(s, v)
	}
}

// 获取目标服务器的脏数据
func (c *PropsSyncContainer) getDirtyProps(srvType uint32) []IProp {
	m, ok := c.DirtySrvProps[srvType]
	if !ok {
		m = make([]IProp, 0, 10)
		c.DirtySrvProps[srvType] = m
	}
	return m
}

// 从同步消息中获取数据
func (this *PropsSyncContainer) ReadSyncProps(li []*protomsg.SyncProp) {
	for _, msg := range li {
		p := this.GetPropRaw(msg.Index)
		p.ReadSyncProp(msg)
		p.SetDirty()
	}
}

// 打包主客户端关心的属性
func (this *PropsSyncContainer) PackMRloeProps() []*protomsg.SyncProp {
	fli := make([]IProp, 0, len(this.PropList))
	this.ForEachProp(func(p IProp) {
		if p.GetField().IsMRole &&
			p.GetField().MainSrv == global.GetCfgInst().GetDefType() {
			fli = append(fli, p)
		}
	})
	return PackPropsToProtobuf(fli)
}

//打包
////////////////////////////////////////////////////////////////
//

//
////////////////////////////////////////////////////////////////
